package demo2;

/**
 * 为什么volatile没有保证原子性?
 * 以下的代码出现了线程安全问题的原因就是因为没有保证count++的操作是原子性的
 * 因为volatile只能保证对于下次读取的线程能够读到最新的值，并不能对已经完成读取操作的
 * 线程产生影响，也就是说当一个线程load，count的值后被调走，另一个线程进入，load后执行完所有的count++操作，刷回了主内存，
 * 而t1线程已经load了count的旧值，他仍会执行后续指令将旧值++，再刷回主内存，进行了覆盖操作
 * 所以这里加了volatile和没有加并没有产生很大的影响，这里主要是count++操作不是原子性产生出来的线程安全问题
 * volatile无法保证复合操作的原子性如count++，就算对于非复合操作也无法保证原子性，只能保证被修饰的变量的可见性，以及其有序性
 */
public class DEMO_06 {
    public static void main(String[] args) throws InterruptedException {
        Counter counter=new Counter();
        Thread t1 =new Thread(()->{
            for (int i = 0; i <5_0000 ; i++) {
                counter.increase();
            }
        });
        Thread t2 =new Thread(()->{
            for (int i = 0; i <5_0000 ; i++) {
                counter.increase();
            }
        });
        t1.start();
        t2.start();
        t1.join();
        t1.join();
        System.out.println(counter.count);
    }
}
class Counter{
    public volatile int count=0;
    public void increase(){
        count++;
    }
}
